#pragma once

#include "network/fd.hpp"

#include <sys/socket.h>

namespace ibox::network {

// socket 文件描述符
class SocketFd : public Fd {
public:
    SocketFd() = default;
    explicit SocketFd(int fd) : Fd(fd) {}
    explicit SocketFd(const Fd &fd) : Fd(fd) {}

public:
    static SocketFd create_socket(int domain, int type, int protocol);
    static SocketFd create_tcp_socket();

public: // socket相关的操作
    int connect(const struct sockaddr *addr, socklen_t addrlen);

    int bind(const struct sockaddr *addr, socklen_t addrlen);
    int listen(int backlog);
    int accept(struct sockaddr *addr, socklen_t *addrlen);

    ssize_t send(const void *data_ptr, size_t data_size, int flag);
    ssize_t recv(void *data_ptr, size_t data_size, int flag);

    int shutdown(int howto);

public: // socket相关的设置
    bool
    get_socket_opt(int level, int optname, void *optval, socklen_t *optlen);
    bool set_socket_opt(int level, int optname, int optval);
    bool set_socket_opt(int level,
                        int optname,
                        const void *optval,
                        socklen_t optlen);

    bool set_reuse_address(bool enable); // 设置可重用地址
    bool set_broadcast(bool enable);     // 设置是否允许广播
    bool set_keepalive(bool enable);     // 设置是否开启保活

    bool set_recv_buffer_size(int size); // 设置接收缓冲大小
    bool set_send_buffer_size(int size); // 设置发送缓冲大小

    bool set_recv_low_water(int size); // 设置接收低水位标记
    bool set_send_low_water(int size); // 设置发送低水位标记

    bool set_linger(bool enable, int linger = 0); // 设置延迟关闭
};

} // namespace ibox::network
